﻿using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace 序列化工具
{
    /// <summary>
    /// 序列化器，用于提供对实例的序列化操作
    /// </summary>
    public static class 序列化器
    {
        
        public static List<值结构> 序列化类(object 实例,string 上一级路径=null, List<值结构> 值结构组=null)
        {
            if (值结构组 == null) {  值结构组 = new List<值结构>(); }
            if (实例 == null) { return 值结构组; }
            //首先判断，序列化的物件是否需要再进一步序列化，若不是则直接序列化后返回
            var 类型 = 类型判断器.基础类型判断(实例);
            if (类型 != 类型判断器.类型.未知)
            {
                序列化值(类型, 实例, 值结构组, 上一级路径);
                return 值结构组;
            }
            else 
            {
                序列化值(类型, 实例, 值结构组, 上一级路径);
                return 值结构组;
            }


            return 值结构组;
        }

        private static void 序列化值(类型判断器.类型 类型, object 实例, List<值结构> 值结构组,string 上一级路径)
        {
            switch (类型)
            {
                case 类型判断器.类型.int数字:
                    从基本类型<int>(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.float数字:
                    从基本类型<float>(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.double数字:
                    从基本类型<double>(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.decimal数字:
                    从基本类型<decimal>(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.long数字:
                    从基本类型<long>(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.bool值:
                    从基本类型<bool>(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.字符串:
                    if (实例 == null) { return; }
                    从基本类型<string>(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.类:
                    从复合类型(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.列表:
                    从列表或数组(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.字典:
                    从字典或键值对(实例, 值结构组, 上一级路径);
                    break;
                case 类型判断器.类型.未知:
                    从复合类型(实例, 值结构组, 上一级路径);
                    break;
            }
        }

        private static void 从基本类型<T>(object 实例, List<值结构> 值结构组, string 上一级路径)
        {
            var 值 = 值类型转换<T>(实例);
            var 值结构 = 创建值结构(实例, 上一级路径);
            值结构组.Add(值结构);
        }

        private static void 从复合类型(object 实例, List<值结构> 值结构组, string 上一级路径)
        {
            
            var 类信息 = 实例.GetType();
            var 字段集 = 类信息.GetFields();
            上一级路径 += $"<{类信息.FullName}>"; 
            
       
            foreach (var 字段 in 字段集)
            {
                序列化类(字段.GetValue(实例), $"{上一级路径}{字段.Name}#",值结构组);
            }
        }

        private static void 从列表或数组(object 实例, List<值结构> 值结构组, string 上一级路径) 
        {
            var 列表或数组 = 实例 as IList;
            int 数组指针 = 0;
            foreach (var 值 in 列表或数组)
            {
                序列化类(值, 上一级路径 + $"List[{数组指针}]#",值结构组);
                数组指针++;
            }
            var 值结构 = 创建值结构(实例, 上一级路径);
            if (值结构.类型文本.Contains('`')) { return; }
            值结构组.Add(值结构);
        }

        private static void 从字典或键值对(object 实例, List<值结构> 值结构组, string 上一级路径)
        {
            var 键值对集 = 实例 as IDictionary;
            int 字典指针 = 0;
            foreach (System.Collections.DictionaryEntry 值 in 键值对集)
            {
                序列化类(值.Key, 上一级路径 + $"Dict[{字典指针}].Key#", 值结构组);
                序列化类(值.Value, 上一级路径 + $"Dict[{字典指针}].Value#", 值结构组);
                字典指针++;
            }
            var 值结构 = 创建值结构(实例, 上一级路径);
            if (值结构.类型文本.Contains('`')) { return; }
            值结构组.Add(值结构);
        }

        public static T 值类型转换<T>(object 实例)
        {
            T 值 = (T) 实例;
            return 值;
        }

        public static 值结构 创建值结构<T>(T 值,string 上一级路径)
        {
            var 值结构 = new 值结构()
            {
                值文本 = 值.ToString(),
                类型 = 值.GetType(),
                类型文本 = 值.GetType().FullName,
                绝对路径 = 上一级路径.Trim('#')
            };
            return 值结构;
        }

        
    }
}
